home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr22 / dtkclk11.zip / DTKCLOCK.DOC < prev    next >
Text File  |  1993-05-06  |  13KB  |  258 lines

  1.          PROGRAMS TO HANDLE "DTK" CLOCK/CALENDAR BOARD
  2.           (based on the OKI 5832 clock/calendar chip)
  3.  
  4.                  Version 1.10
  5.  
  6.                    Richard B. Wales
  7.                   July 1989
  8.               Internet mail:  wales@CS.UCLA.EDU
  9.                 CompuServe:  70521,301
  10.  
  11.  
  12. (C) Copyright 1989 Richard B. Wales.  All Rights Reserved.
  13. These programs, SAVECLK and READCLK, may be freely copied and distributed
  14. for commercial or non-commercial use, provided:
  15.  
  16.     (1) the source code is included in any distribution;
  17.     (2) all copyright notices are retained intact; and
  18.     (3) no charge (other than a reasonable copying or communications
  19.         charge) is assessed.
  20.  
  21. I believe these programs are bug-free.  However, I disclaim any and all
  22. liability for any damages, including incidental or consequential damages,
  23. which might result from your use of these programs.
  24.  
  25.  
  26. WHY I WROTE THESE PROGRAMS
  27.  
  28. My original home computer (a Taiwanese "turbo" XT clone) had a built-in
  29. clock/calendar on the motherboard.  When I upgraded to a 286-based
  30. motherboard, I lost this feature and had to go buy an outboard clock.
  31. Since I already had all the serial and parallel ports I needed, I didn't
  32. want to waste money on an "everything-but-the-kitchen-sink" multifunction
  33. card.  I ended up buying a clock/calendar card by DTK (a Taiwanese com-
  34. pany specializing in various kinds of PC accessories, most of which come
  35. with documentation that doesn't identify the company at all).
  36.  
  37. Two programs came with my new DTK clock card:  SETTIME (to set the time
  38. in both the system and the clock card), and AUTOTIME (to read the time
  39. from the clock card and set the system time accordingly).  I quickly grew
  40. to dislike these programs.  Not only were their user interfaces horrid
  41. (e.g., SETTIME required you to input the new time in the form HH-MM-SS,
  42. with minus signs instead of colons; and AUTOTIME cleared the screen even
  43. if the output was redirected to NUL), but these programs exited via the
  44. ancient DOS "Int 27" (TSR) call -- leaving the program permanently resi-
  45. dent in memory for no good reason at all.  A further botherance was that,
  46. no matter what I input for the "seconds" portion of the time, SETTIME
  47. would always end up resetting the seconds to zero.
  48.  
  49. Resolving to improve on the DTK software, I studied them via a disassembler
  50. (to figure out how to interface with the clock card).  Additionally, I
  51. called the manufacturer of the clock/calendar chip (Oki Semiconductor)
  52. and got a complimentary copy of their IC data book and application notes
  53. for the "5832" chip which DTK used.
  54.  
  55. The two programs offered here (SAVECLK and READCLK) are the result of this
  56. study.  As it turned out, the resetting of the "seconds" portion of the
  57. time to zero is a misfeature of the 5832 chip itself -- not the SETTIME
  58. program.  However, I was able to fashion a kludge that permits the time to
  59. be stored to within +/- 5 seconds of the actual value.
  60.  
  61.  
  62. USER INTERFACE TO THE "SAVECLK" AND "READCLK" PROGRAMS
  63.  
  64. SAVECLK does not contain its own routine to query the user for the date
  65. and time.  Rather, it uses whatever date/time has already been set in the
  66. system (e.g., via the DOS commands DATE and TIME).  After changing the
  67. system date/time (via DATE and TIME, or any other desired program), simply
  68. type "SAVECLK" to store the new information in the clock card.
  69.  
  70. READCLK reads the clock card value and sets the system date/time accordingly.
  71. You may wish to insert the command "READCLK" into your AUTOEXEC.BAT file.
  72.  
  73. Due to a hardware design flaw, the DTK card is "frozen" on power-up, and
  74. remains frozen until you do a READCLK.  In order to get around this bug,
  75. READCLK may be called with a single numeric argument (in the range 1 to 119),
  76. giving a value in seconds which should be added to the clock.  On my system,
  77. for example, I have the command "READCLK 33" near the start of my AUTOEXEC.BAT
  78. file -- since it takes about 33 seconds to get to the READCLK command from a
  79. power-up.  This "freezing" also takes place if you hit the "reset" button, but
  80. it does not happen if you reboot via CTRL-ALT-DEL.  However, READCLK checks to
  81. see whether you are doing a "warm" reboot (by looking at the byte at location
  82. 0040:0072), and it will skip the resetting of the clock board in such cases.
  83.  
  84. SAVECLK and READCLK each generates three lines of output.  If you wish, you
  85. may redirect this output to a file, or to NUL.
  86.  
  87.  
  88. THE DTK CLOCK/CALENDAR CARD
  89.  
  90. The DTK clock/calendar card consists basically of a 5832 clock chip (with
  91. a backup battery) and an 8255 programmable peripheral interface (PPI) chip.
  92. The card responds to the four I/O ports 020Ch through 020Fh, as follows:
  93.  
  94.     020Ch:  clock data port (PPI port A; 4 low-order bits only)
  95.     020Dh:  clock address port (PPI port B; 4 low-order bits only)
  96.     020Eh:  clock control lines (PPI port C; 4 high-order bits only)
  97.     020Fh:  PPI control lines (all 8 bits)
  98.  
  99. Note that the assignment of the three PPI ports to the various parts of the
  100. clock chip was more or less arbitrary on DTK's part -- as was the choice of
  101. the particular block of four consecutive I/O ports.
  102.  
  103. A detailed description of the 8255 PPI is beyond the scope of these notes.
  104. However, it may be noted that only three values for the PPI control port
  105. (020Fh) are useful in this application:
  106.  
  107.       90h:  read from port A (data);
  108.         write to ports B (address) and C (control)
  109.       80h:  write to ports A (data), B (address), and C (control)
  110.       00h:  disable PPI (no access to clock)
  111.  
  112. The clock control lines are connected to port 020Eh of the PPI as follows:
  113.  
  114.       80h:  select (enable access to) clock
  115.       40h:  "hold" (freeze) clock value for reading
  116.         (also used when writing a new value to clock)
  117.       20h:  enable reading clock's current value
  118.       10h:  enable writing new value to clock
  119.  
  120. As with the assignment of PPI ports, the assignment of these control lines
  121. to these particular bits of PPI port C was more or less arbitrary on DTK's
  122. part.
  123.  
  124. The data items on the clock chip are addressed as follows; this assignment
  125. is built into the 5832 chip:
  126.  
  127.       0Ch:  tens digit of year
  128.       0Bh:  units digit of year
  129.       0Ah:  tens digit of month
  130.       09h:  units digit of month
  131.       08h:  tens digit of day (see notes below)
  132.       07h:  units digit of day
  133.       06h:  day of the week
  134.       05h:  tens digit of hour (see notes below)
  135.       04h:  units digit of hour
  136.       03h:  tens digit of minute
  137.       02h:  units digit of minute
  138.       01h:  tens digit of second
  139.       00h:  units digit of second
  140.  
  141. The "tens digit of hour" data item also contains 12/24-hour and AM/PM info
  142. in the high-order bits:  08h = 24-hour clock; 04h = 12-hour clock, PM;
  143. 00h = 12-hour clock, AM.  (Only the 24-hour format is used by SAVECLK and
  144. READCLK.)
  145.  
  146. The "tens digit of day" data item also contains a high-order bit (04h) if
  147. the next February will have 29 days instead of 28.  This bit may be set at
  148. any time starting with March 1 of the preceding year; it will remain set
  149. until February 29 has passed, and is automatically reset on March 1.
  150.  
  151. The 5832 chip does not store the "century" part of the year.  The SAVECLK
  152. and READCLK programs assume that the year is between 1980 and 2079 -- a
  153. hopefully safe assumption. :-)
  154.  
  155. Reading the clock is fairly simple.  After setting up some preliminary
  156. values in the various I/O ports, the program outputs an address to the
  157. "clock address" port, then reads a value from the "clock data" port.  Note
  158. that the 5832 chip requires up to 6 uS after the address has been specified
  159. before the data is guaranteed to be readable; this time is expended via a
  160. wait loop in the program.
  161.  
  162. While it is possible to "hold" the clock while reading it, an approach that
  163. works just as well (and which is used in these programs) is to simply read
  164. the clock starting at the low-order end (i.e., seconds first) -- and then to
  165. re-read the seconds digit.  If the seconds digit has not changed during the
  166. course of reading, then all is well; otherwise, the clock is read over again.
  167.  
  168. Writing to the clock requires the use of the "hold" signal, followed by a
  169. delay of at least 150 uS.  Then, each digit is written in turn, followed by
  170. a "write" signal lasting at least 1 uS.  A misfeature of the 5832 causes the
  171. seconds data to be cleared to zero instead of being set to the value being
  172. written; this is compensated for to some extent in the SAVECLK and READCLK
  173. programs by fiddling with the "day of the week" value, as described below.
  174.  
  175. Only the low-order four bits of each data byte read from or written to the
  176. clock are significant.  When reading from the clock, the four high-order bits
  177. of each byte are 1's and need to be masked out; when writing, the four high-
  178. order bits of each byte are simply ignored by the clock.
  179.  
  180.  
  181. HANDLING OF SECONDS ON THE 5832 CLOCK CHIP
  182.  
  183. The 5832 chip includes a "seconds" value in its output.  However, whenever
  184. a new value is written to the clock, the "seconds" are -- for reasons known
  185. only to the designers of the chip -- reset to zero.
  186.  
  187. After quite a bit of thought, I managed to fabricate an obscure scheme for
  188. storing a bit more precision in the time value stored in the clock by my
  189. SAVECLK program.  The 5832 chip includes a "day of the week" value, which
  190. can be set arbitrarily by the software (and which is incremented each day
  191. by the chip).  The 5832 makes no effort to validate the day of the week.
  192. By storing a bogus "day of the week" value in the chip -- and comparing the
  193. chip's information (as read later by READCLK) with the true day of the week
  194. corresponding to the date -- I managed to store a constant multiple of 10
  195. seconds as a fixed offset to be added to the clock output.
  196.  
  197. What I do is this:  When setting the time in SAVECLK, I use a perpetual cal-
  198. endar algorithm (courtesy of Martin Gardner) to figure out the true day of
  199. the week corresponding to the date.  I then add to this the number of seconds
  200. (divided by ten, with the remainder thrown away) in the time.  Thus, for
  201. instance, if the true day of the week is Monday, and the current time to be
  202. stored in the clock card ends with 10 seconds, I add one to the day and store
  203. "Tuesday" as the day of the week on the card.  For 20 seconds, I would change
  204. the day from Monday to Wednesday; and so on.
  205.  
  206. Also, before doing any of the above, I add 5 seconds to the date/time I intend
  207. to store in the clock card.  This means that I leave the day of the week alone
  208. from 55 through 4 seconds; add one day from 5 through 14 seconds; two days for
  209. 15-24 seconds; and so on.  By doing this, I effectively set the clock card to
  210. within +/- 5 seconds of the correct time.
  211.  
  212. When I read the time back in READCLK, I compute the true day of the week for
  213. the date off of the card, and compare it with the day of the week I read from
  214. the card.  I then multiply the difference (modulo 7, of course) by 10 seconds
  215. and add that value to the date/time from the clock card.
  216.  
  217. The clock card uses the seven values 0-6 to represent the day of the week.
  218. Since the 5832 chip doesn't attempt to validate the day of the week in any
  219. way, the correspondence between days and numeric values is arbitrary.  I chose
  220. to use the DOS convention (0 = Sunday), for clarity if nothing else.
  221.  
  222. Note that I couldn't simply store the "tens of seconds" data as a raw figure
  223. in the "day of the week" slot of the clock -- since this figure gets incre-
  224. mented every day, and when reading the clock back later on I have no way of
  225. knowing how many days have elapsed since I last set the time.  The only way to
  226. store this extra data was to make it into an offset relative to the correct
  227. day of the week.
  228.  
  229.  
  230. COMPILING THE SOURCE
  231.  
  232. These programs were compiled with Borland Turbo C 1.5, using the "tiny"
  233. memory model, and converted to .COM files via EXE2BIN.
  234.  
  235. I have include .PRJ files for both SAVECLK and READCLK, for compilation under
  236. Turbo C's integrated environment.  Note that the linker will give a warning
  237. about there not being a "stack" segment; this is an inevitable consequence of
  238. using the "tiny" memory model, and you may safely ignore the warning.
  239.  
  240. I have also included the TCCONFIG.TC file I used for these programs.  If you
  241. compile the source yourself, be sure to go into the "Directories" item in the
  242. "Options" menu and change the various Turbo C directories from the ones I use
  243. (I installed my Turbo C stuff in C:\MISC\TC15) to the ones you use.
  244.  
  245.  
  246. KNOWN PROBLEMS
  247.  
  248. If the clock has not been set at all (e.g., you just replaced the lithium
  249. battery), READCLK will set your system time to a strange value and will not
  250. realize anything is wrong.
  251.  
  252. If you do a CTRL-ALT-DEL reboot, followed later on by a "reset button" reboot
  253. (without powering the system off), READCLK will think the second reboot was a
  254. "warm" reboot, and it will not reset the clock board forward by the number of
  255. seconds given in the argument.  I suppose I could fix this by having READCLK
  256. change the value in 0040:0072 from 34H (the "warm boot" flag) to something
  257. else, but I didn't want to interfere with anything else in the system that
  258. might care about this value.